#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#include "user_buzz.h"
#include <sys/types.h>
#include <sys/syscall.h>

#define THREADCOUNT 100
#define GOLD 30
#define BLACK THREADCOUNT-GOLD
#define THREADPOOL 5   

#define TIMEOUT 10  // in us
#define ACTIVITY 5 // in us


bzz_t GTLOCK;
int thread_num = 0;

void *thr_routine(void *k); 





void thread(){
    struct timeval t1,t2;
    double elapsedTime;
    int ID = thread_num;
    
    
    if(ID % 5) { 
            bzz_color(BZZ_GOLD,GTLOCK); 
    } else {
            bzz_color(BZZ_BLACK,GTLOCK);
    }
    
    gettimeofday(&t1,NULL);
    bzz_lock(GTLOCK);
    usleep(ACTIVITY); // ACTIVITY
    bzz_release(GTLOCK);
    gettimeofday(&t2,NULL);
    
    elapsedTime = (t2.tv_sec - t1.tv_sec);      // sec 
    elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000000.0;   //  us
    
     if(ID % 5) { 
            printf("%d GOLD = %f\n",ID, elapsedTime);
            //printf("%d wait GOLD %us %uus \n",ID, t2.tv_sec - t1.tv_sec,t2.tv_usec - t1.tv_usec); 
    } else {
            printf("%d BLACK = %f\n",ID, elapsedTime);
            //printf("%d wait BLACK %us %uus \n",ID, t2.tv_sec - t1.tv_sec,t2.tv_usec - t1.tv_usec);
    }

    
	
}

void *thr_routine(void *k) {
    
    thread_num = (int)k;

    thread();
    
	pthread_exit(NULL);
}

int main() {
	int NUM_THREADS = 100;
	pthread_t threads[NUM_THREADS];	
	int rc;
   	long t;
   	init_bzz(&GTLOCK,THREADPOOL,TIMEOUT); 
   	
   	for(t=0; t<NUM_THREADS; t++){
      		//printf("In main: creating thread %ld\n", t);
		rc = pthread_create(&threads[t], NULL, thr_routine, (void *)t);
      		if (rc){
         		//printf("ERROR; return code from pthread_create() is %d\n", rc);
         		exit(-1);
      		}
      		
 	}
 	 bzz_kill(GTLOCK);
  	 pthread_exit(NULL);
}
